home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / patches / a1200_hdpatch / src / a1200_hdpatch.c next >
C/C++ Source or Header  |  1996-04-07  |  6KB  |  202 lines

  1. /*
  2.  *  Initial-Release V1.0:
  3.  *   Mon Dec 26 00:20:04 1994 - R.Hess
  4.  *   Mon Dec 26 12:19:45 1994 - R.Hess
  5.  *
  6.  *   V1.0: (31.12.94) Kleine Änderung in der Ausgabe.
  7.  *         Sat Dec 31 17:29:12 1994 - R.Hess
  8.  *
  9.  *   V1.1: Forbid()/Permit() wenn in die KickTag-Feldern geschrieben
  10.  *         wird. Danach die Caches leeren (mit CacheClearU()), damit
  11.  *         nichts im Cache stecken bleibt.
  12.  *         Sun Jan  8 06:18:32 1995 - R.Hess
  13.  *
  14.  *   V1.1: Copyright 1994/95 eingefügt.
  15.  *         Thu Jan 26 23:45:53 1995 - R.Hess
  16.  *         Neuübersetzung mit SAS/C 6.55.
  17.  *         Mon Mar 20 13:48:38 1995 - R.Hess
  18.  *
  19.  *   Reference: M&T AMIGA-Magazin 10/88, Seite 51
  20.  *
  21.  *   Compiler- und Linkaufrufe (SAS/C 6.55): siehe smakefile
  22.  */
  23.  
  24. #include <exec/types.h>
  25. #include <exec/resident.h>
  26. #include <exec/memory.h>
  27. #include <exec/types.h>
  28. #include <exec/nodes.h>
  29. #include <exec/execbase.h>
  30.  
  31. #include <clib/exec_protos.h>
  32. #include <clib/dos_protos.h>
  33.  
  34. #include <pragmas/exec_pragmas.h>
  35. #include <pragmas/dos_pragmas.h>
  36.  
  37. #include <string.h>
  38.  
  39. #include "A1200_HDPatch.h"
  40.  
  41. #define AUTOR        "Copyright (c) 1994/95 by Rainer Hess"
  42.  
  43. #define VSTRINGLEN    36    /* Länge des Strings in Name */
  44. #define AUTORLEN    37    /* Länge des Strings in idString */
  45.  
  46. UBYTE *v = VERSTAG " " AUTOR;
  47.  
  48. extern struct ExecBase *SysBase;
  49. extern struct DosLibrary *DOSBase;
  50.  
  51. /*
  52.  * erweiterte MemList Struktur mit insgesamt 4 MemEntrys
  53.  */
  54.  
  55. struct
  56.   {
  57.     struct MemList me_main;
  58.     struct MemEntry me_added[3];
  59.     UBYTE me_Name[VSTRINGLEN];
  60.     UBYTE me_idString[AUTORLEN];
  61.   }
  62.  *Speicher;
  63.  
  64. struct Resident myProg =
  65. {
  66.   RTC_MATCHWORD,        /* Matchword $4afc, daran wir Res. Str. erkannt */
  67.   NULL,                /* Zeiger auf sich selbst                       */
  68.   NULL,                /* Zeiger auf Strukturende                      */
  69.   RTF_COLDSTART,        /* Flags                                        */
  70.   VERSION,            /* Version                                      */
  71.   NT_UNKNOWN,            /* Type                                         */
  72.   104,                /* Prioritaet (nach exec.library)               */
  73.   NULL,                /* Zeiger auf Name                              */
  74.   NULL,                /* und ID_String                                */
  75.   NULL                /* Zeiger auf Code                              */
  76. };
  77.  
  78. /*
  79.  * Diese Funktion wird resetfest installiert.
  80.  * ------------------------------------------
  81.  * ACHTUNG! Keine weiteren Funktionen daraus aufrufen, es muss
  82.  * alles innerhalb dieser Funktion sein, sonst gibt es GURU's,
  83.  * da der Speicher sonst falsch initalisiert wird. Andernfalls
  84.  * muß man wohl alle Funktionen einzeln vermerken...
  85.  */
  86.  
  87. void __saveds
  88. ResetProg (void)
  89. {
  90.   //char *cia = (char *) 0xbfe001;    /* Nur für Testzwecke! */
  91.   long i;
  92.  
  93.   Forbid();
  94.  
  95.   /*
  96.    * Achtung! Kein Optimize verwenden, da sonst diese
  97.    * geniale Warte-Schleife in ein NICHTS eleminiert wird.
  98.    * 350000 ist eben der ermittelte Wert auf einem A1200 mit
  99.    * dem Blizzard Turbo-Memory-Board 1220/4. Auf schnelleren
  100.    * Boards ist dieser Wert eben zu erhöhen.
  101.    */
  102.  
  103.   //*cia |= (1 << 1);        /* PowerLed ausschalten (zum Test) */
  104.   for(i=0; i<350000; i++);    /* Tolle Warte-Routine :-)         */
  105.   //*cia &= ~(1 << 1);        /* PowerLed einschalten (zum Test) */
  106.  
  107.   Permit();
  108. }
  109.  
  110. void
  111. main(int argc, char *argv[])
  112. {
  113.   BYTE *Mem, *ResAdr;
  114.   register BYTE *MemPoi, *i;
  115.   int c;
  116.  
  117.   if (SysBase->LibNode.lib_Version < 36L)
  118.     {
  119.       Write (Output(), "Benötige Kickstart V36 oder höher! Abbruch...\n", 46L);
  120.       Exit (RETURN_ERROR);
  121.     }
  122.  
  123.   /*
  124.    * Speicher fuer MemList Struktur anfordern (wird automatisch geloescht)
  125.    */
  126.  
  127.   Speicher = AllocMem (sizeof (*Speicher), MEMF_PUBLIC | MEMF_CLEAR);
  128.   Speicher->me_main.ml_Node.ln_Type = NT_MEMORY;    /* Nodetyp */
  129.   Speicher->me_main.ml_NumEntries = 4;    /* 4 MemEntry Strukturen vorhanden */
  130.  
  131.   /*
  132.    * Name und idString einkopieren.
  133.    */
  134.  
  135.   strncpy (Speicher->me_Name, VSTRING, VSTRINGLEN);
  136.   strncpy (Speicher->me_idString, AUTOR, AUTORLEN);
  137.  
  138.   myProg.rt_Name = Speicher->me_Name;
  139.   myProg.rt_IdString = Speicher->me_idString;
  140.  
  141.  
  142.   /*
  143.    * Code in Speicherbereich kopieren
  144.    */
  145.  
  146.   Mem = AllocMem ((ULONG) main - (ULONG) ResetProg, MEMF_PUBLIC);
  147.   for (i = (BYTE *) ResetProg, MemPoi = Mem; i < (BYTE *) main; *MemPoi++ = *i++);
  148.   myProg.rt_Init = (APTR) Mem;    /* jetzt Codeadresse in Resident Struktur eintragen */
  149.  
  150.   /* und Code-Speicher in MemList Struktur vermerken (Adresse, Laenge)
  151.    *******************************************************************/
  152.  
  153.   Speicher->me_main.ml_ME[0].me_Addr = (APTR) Mem;
  154.   Speicher->me_main.ml_ME[0].me_Length = (ULONG) main - (ULONG) ResetProg;
  155.  
  156.   /*
  157.    * Jetzt Resident Struktur in Speicherbereich kopieren
  158.    */
  159.  
  160.   Mem = AllocMem (sizeof (struct Resident), MEMF_PUBLIC);
  161.   myProg.rt_MatchTag = (struct Resident *) Mem;    /* Zeiger auf sich selbst setzen */
  162.   myProg.rt_EndSkip = (APTR) (Mem + sizeof (struct Resident));    /* Zeiger auf Ende */
  163.   for (i = (BYTE *) & myProg, MemPoi = Mem, c = 0; c < sizeof (struct Resident); *MemPoi++ = *i++, c++);
  164.  
  165.   /*
  166.    * Und Speicherbereich in MemList vermerken
  167.    */
  168.  
  169.   Speicher->me_main.ml_ME[1].me_Addr = (APTR) Mem;
  170.   Speicher->me_main.ml_ME[1].me_Length = sizeof (struct Resident);
  171.   ResAdr = Mem;                /* merken */
  172.  
  173.   /*
  174.    * Resident-Tabelle erstellen (2 Zeiger, zweiter Zeiger ist 0)
  175.    */
  176.  
  177.   Mem = AllocMem (sizeof(struct MemChunk), MEMF_PUBLIC | MEMF_CLEAR);
  178.   *((ULONG *) Mem) = (ULONG) ResAdr;        /* Adresse Resident Struktur eintragen */
  179.   Speicher->me_main.ml_ME[2].me_Addr = (APTR) Mem;
  180.   Speicher->me_main.ml_ME[2].me_Length = sizeof(struct MemChunk);
  181.  
  182.   /*
  183.    * Jetzt MemList selbst auch noch in MemList vermerken
  184.    * ACHTUNG! Bei KickMemPtr und KickTagPtr = wird jedes
  185.    * andere resetfeste Programm gelöscht.
  186.    */
  187.  
  188.   Speicher->me_main.ml_ME[3].me_Addr = (APTR) Speicher;
  189.   Speicher->me_main.ml_ME[3].me_Length = sizeof (*Speicher);
  190.  
  191.   Forbid();
  192.   SysBase->KickMemPtr = (APTR) Speicher;    /* MemList Adresse   in KichMemPtr (546) */
  193.   SysBase->KickTagPtr = (APTR) Mem;        /* Resident Mem.Adr. in KickTagPtr (550) */
  194.   SysBase->KickCheckSum = (APTR) SumKickData();    /* Neue KickCheckSum berechnen */
  195.   Permit();
  196.  
  197.   CacheClearU();    /* Damit auch alles ins RAM geschrieben wird und nicht was im Cache stecken bleibt */
  198.  
  199.   if( argc != 0) Printf ("%s installiert...\n", VERS);    /* Kein WBStart */
  200.   Exit (RETURN_OK);
  201. }
  202.